<template>
  <div ref="tableContainerEl" class="w-full h-full sl-table-container">
    <a-table
      :class="{
        'table-body-nowrap': bodyNowrap,
        'table-header-nowrap': headerNowrap,
        'sl-table-empty': dataSource && dataSource.length === 0,
        'sl-pagination-px0': !pgPaddingX,
      }"
      v-bind="$attrs"
      :pagination="pagination || false"
      :data-source="dataSource"
      :scroll="fit ? { x: true, y: bodyHeight } : ($attrs.scroll as TableProps['scroll'])"
    >
      <template #bodyCell="options: BodyCellOptions">
        <slot name="bodyCell" v-bind="options" />
      </template>
      <template v-if="hasRowRender" #expandedRowRender="options: ExpandedRowRenderOptions">
        <slot name="expandedRowRender" v-bind="options" />
      </template>
      <template #emptyText>
        <SlEmpty :description="$attrs.loading ? t('common.loading') : emptyText" />
      </template>
      <template #summary>
        <slot name="summary" />
      </template>
    </a-table>
    <slot />
  </div>
</template>
<script lang="ts">
export default {
  inheritAttrs: false,
};
</script>
<script lang="ts" setup>
import type { BodyCellOptions, ExpandedRowRenderOptions } from "/@/types/antd";
import type { SearchModel } from "/@/api/models";
import SlEmpty from "/@/components/SlEmpty.vue";
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { useI18n } from "/@/locales/useI18n";
import { useEmptyText } from "/@/hooks/useEmptyText";
import ResizeObserver from "resize-observer-polyfill";
import type { TableProps, TablePaginationConfig } from "ant-design-vue";
import { StyleConst } from "/@/base/data";

const props = withDefaults(
  defineProps<{
    // tableProps: TableProps;
    fit?: boolean;
    searchModel?: SearchModel;
    ignoreKeys?: string[];
    bodyNowrap?: boolean;
    headerNowrap?: boolean;
    pagination?: TablePaginationConfig;
    dataSource?: TableProps["dataSource"];
    hasRowRender?: boolean;
    pgPaddingX?: boolean;
  }>(),
  {
    fit: true,
    bodyNowrap: true,
    headerNowrap: true,
  }
);
const { t } = useI18n();

//搜索结果为空时的提示跟空数据的提示不同
const { emptyText, modelForEmptyText } = useEmptyText(props);
watch(
  () => props.searchModel,
  (v) => {
    modelForEmptyText.value = v;
  },
  {
    deep: true,
  }
);

const tableContainerEl = ref<HTMLDivElement>();
const bodyHeight = ref<number | string>(200);
let resizeObserver: ResizeObserver | null;
onMounted(() => {
  if (tableContainerEl.value) {
    const containerEl = tableContainerEl.value;
    //实现自适应div container的大小
    let first = true;
    resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
      const entry = entries[0];
      // console.log("========>ResizeObserver resize", entry.contentRect.height);
      if (entry && entry.contentRect.height) {
        resizeBody(containerEl, entry.contentRect.height, first ? false : !!props.pagination);
        first = false;
      }
    });
    resizeObserver.observe(tableContainerEl.value);
  }
});
function resizeBody(containerEl: HTMLDivElement, containerHeight: number, hasPagination: boolean) {
  const bodyWidth = document.body.offsetWidth;
  const bodyEl = containerEl.querySelector("div.ant-table-body") as HTMLDivElement;
  if (bodyWidth <= StyleConst.breakpoint.lg) {
    //移动端 不再自适应
    bodyEl && (bodyEl.style.height = "");
    bodyHeight.value = "";
    return;
  }
  let headerEl: HTMLElement | null = null;
  headerEl = containerEl.querySelector("div.ant-table-header") as HTMLElement;
  if (!headerEl) {
    headerEl = containerEl.querySelector("thead.ant-table-thead") as HTMLElement;
  }
  const pgEl = containerEl.querySelector("ul.ant-pagination") as HTMLElement;
  // console.log("====>pgEl", pgEl);
  const summaryEl = containerEl.querySelector("div.ant-table-summary") as HTMLElement;
  // bodyHeight.value =
  //   containerHeight - (headerEl ? headerEl.offsetHeight : 0) - (hasPagination ? StyleConst.paginationHeight : 0);
  bodyHeight.value =
    containerHeight -
    (headerEl ? headerEl.offsetHeight : 0) -
    (pgEl ? pgEl.offsetHeight : 0) -
    (summaryEl ? summaryEl.offsetHeight : 0);
  if (bodyEl) {
    bodyEl.style.height = bodyHeight.value + "px";
  }
}
let lastIsEmpty: boolean | null = null;
watch(
  () => props.dataSource,
  (data) => {
    nextTick(() => {
      if (!data || data.length === 0) {
        tableContainerEl.value && resizeBody(tableContainerEl.value, tableContainerEl.value?.offsetHeight, false);
        lastIsEmpty = true;
      } else {
        tableContainerEl.value &&
          resizeBody(tableContainerEl.value, tableContainerEl.value?.offsetHeight, !!props.pagination);
        lastIsEmpty = false;
      }
    });
  }
);
onBeforeUnmount(() => {
  if (resizeObserver) {
    console.log("=======>ResizeObserver unmount");
    resizeObserver.disconnect();
    resizeObserver = null;
  }
});
</script>
<style lang="less">
.table-body-nowrap {
  .ant-table-body,
  .ant-table-summary {
    white-space: nowrap;
  }
}
.table-header-nowrap {
  .ant-table-header {
    white-space: nowrap;
  }
}
.ant-table-wrapper {
  .ant-table-thead > tr > th::before {
    display: none;
  }
  .ant-pagination {
    margin: 0;
    background-color: #fff;
    padding: 0 12px 0 12px;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
    align-items: center;
  }
}
.ant-table-wrapper:not(.no-pagination) {
  .ant-table {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }
}

.ant-table-empty-noborder {
  .ant-table-placeholder {
    .ant-table-cell {
      border: 0;
    }
  }
}
.ant-table-thead > tr > th {
  font-weight: 600;
}
.sl-table-empty {
  .ant-table-body table {
    height: 100%;
    .ant-table-cell {
      border: 0;
    }
  }
}
.ant-pagination.mini {
  height: 50px;
}
.mini {
  .ant-pagination-prev {
    & + .ant-pagination-item {
      margin-left: 5px;
    }
  }
  .ant-pagination-item-link {
    font-size: 16px;
    color: @color-secondary;
  }
  .ant-pagination-disabled {
    .ant-pagination-item-link {
      color: @color-disabled;
    }
  }
  .ant-pagination-item {
    margin-right: 5px;
    a {
      color: @color-secondary;
    }
  }
  .ant-pagination-item-active {
    background-color: #4285f4;
    a {
      color: #fff;
    }
  }
  .ant-pagination-options {
    margin-left: 18px;
  }
  .ant-pagination-total-text {
    flex: 1 1 0;
    color: @color-secondary;
  }
}
.sl-pagination-px0 {
  .ant-pagination {
    padding-left: 0;
    padding-right: 0;
  }
}
</style>
